﻿#include "PlatformWin.h"
#include <iostream>
#include <string>

#define  WINDOWSCLASS_NAME L"NewBieEngine"
namespace EngineCore{

PlatformWin::PlatformWin()
{

}


PlatformWin::~PlatformWin()
{
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	PlatformWin* pWin = reinterpret_cast<PlatformWin*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
	if (pWin->HandleWindowsMessage(hwnd, Message, wParam, lParam))
	{
		return S_OK;
	}
	return DefWindowProc(hwnd, Message, wParam, lParam);
}

LRESULT CALLBACK WndCreateProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	if (WM_CREATE == Message)
	{
		CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
		SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pCreate->lpCreateParams));
		SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc));
		
		return S_OK;
	}
	return DefWindowProc(hwnd, Message, wParam, lParam);
}


_hr PlatformWin::SetUp(const EngineProperty& prop)
{

	{	//Create Windows
		HINSTANCE hInstance = GetModuleHandle(nullptr);

		WNDCLASSEX wc = {};
		wc.cbSize = sizeof(WNDCLASSEX);
		wc.style = CS_VREDRAW | CS_HREDRAW;
		wc.lpfnWndProc = WndCreateProc;
		wc.hInstance = hInstance;
		wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wc.lpszClassName = WINDOWSCLASS_NAME;
		wc.hIcon = LoadIcon(nullptr, IDC_ARROW);

		if (RegisterClassEx(&wc) == FALSE)
		{
			//Return Error Info
		}

		RECT WindowRect = { 0, 0,static_cast<long>(prop.Width),static_cast<long>(prop.Height) };
		AdjustWindowRect(&WindowRect, WS_OVERLAPPEDWINDOW, FALSE);

		m_hwnd = CreateWindowEx(
			0,
			WINDOWSCLASS_NAME,
			prop.AppName,
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			WindowRect.right - WindowRect.left,
			WindowRect.bottom - WindowRect.top,
			nullptr,
			nullptr,
			hInstance,
			this
		);

		if (!m_hwnd)
		{
			//Return Error Info 
			//std::cout << "Failed to create window, Error=0x%.8x"<< GetLastError() << std::endl;
			//return HRESULT_FROM_WIN32(GetLastError());
		}

	}



	return _OK;
}

bool PlatformWin::HandleWindowsMessage(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	//TODO: Process The Windows Message
	switch (Message)
	{
	case WM_KEYDOWN:

		break;
	default:
		return false;
	}
	return true;
}

_hr PlatformWin::Launch()
{
	ShowWindow(m_hwnd, SW_SHOWNORMAL);
	return _OK;
}

_hr PlatformWin::Tick()
{
	MSG msg;
	//TODO: GetMessage To Reduce CPU Use When Windows not Active
	while (PeekMessage(&msg,0,0,0,PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return _OK;
}

PlatformWin::HandleDLL PlatformWin::GetModule(const wchar_t * moduleName)
{
	HMODULE hm = ::LoadLibraryEx(moduleName, nullptr, 0);
	return hm;
}

void * PlatformWin::GetMathod(HandleDLL& hMoudle,const char * procName)
{
	void* proc = ::GetProcAddress(hMoudle, procName);
	return proc;
}

_hr PlatformWin::FreeHandle(HandleDLL& hModule)
{
	::FreeLibrary(hModule);
	return _OK;
}


}